package com.huangkailong.gitimgbed.core;

import de.saxsys.mvvmfx.FluentViewLoader;
import de.saxsys.mvvmfx.FxmlView;
import de.saxsys.mvvmfx.ViewTuple;
import javafx.scene.Scene;
import javafx.stage.Stage;

import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author huangkl
 * @since 1.0.0
 */
public class ViewDispatcher {
    private static Map<Class<? extends FxmlView>, Stage> stageCache = new ConcurrentHashMap<>();
    private static Map<Class<? extends FxmlView>, Scene> scenceCache = new ConcurrentHashMap<>();

    /**
     * 显示视图
     *
     * @param viewType 视图 {@link Class} 对象
     */
    public static void showView(Class<? extends FxmlView> viewType){
        final Stage stage = getStage(viewType);
        Optional.ofNullable(stage).ifPresent(Stage::show);
    }

    /**
     * 关闭视图
     *
     * @param viewType 视图 {@link Class} 对象
     */
    public static void closeView(Class<? extends FxmlView> viewType){
        final Stage stage = getStage(viewType);
        Optional.ofNullable(stage).ifPresent(Stage::close);
    }

    /**
     * 添加 {@link Stage} 对象
     *
     * @param viewType 视图 {@link Class} 对象
     * @param stage {@link Stage}
     */
    public static void addStage(Class<? extends FxmlView> viewType, Stage stage){
        stageCache.put(viewType, stage);
    }

    /**
     * 获取 {@link Class} 对应得 Scene
     * @param viewType 视图 {@link Class} 对象
     * @return {@link Scene}
     */
    public static Scene getScene(Class<? extends FxmlView> viewType){
        Scene scene = scenceCache.get(viewType);
        if(Objects.isNull(scene)){
            synchronized (ViewDispatcher.class){
                scene = scenceCache.get(viewType);
                if(Objects.isNull(scene)){
                    final ViewTuple viewTuple = FluentViewLoader.fxmlView(viewType).load();
                    scene = new Scene(viewTuple.getView());
                    scenceCache.put(viewType, scene);
                }
            }
        }
        return scene;
    }

    /**
     * 获取 {@link Class} 对应得 Stage
     * @param viewType 视图 {@link Class} 对象
     * @return {@link Stage}
     */
    public static Stage getStage(Class<? extends FxmlView> viewType){
        Stage stage = stageCache.get(viewType);
        if(Objects.isNull(stage)){
            synchronized (ViewDispatcher.class){
                stage = stageCache.get(viewType);
                if(Objects.isNull(stage)){
                    stage = new Stage();
                    stage.setScene(getScene(viewType));
                    stageCache.put(viewType, stage);
                }
            }
        }
        return stage;
    }
}
